/***************************************************
 ** @Desc : This file for 充值查询
 ** @Time : 2019.04.11 9:42
 ** @Author : Joker
 ** @File : recharge_query
 ** @Last Modified by : Joker
 ** @Last Modified time: 2019.04.11 9:42
 ** @Software: GoLand
****************************************************/
package controllers

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"net/url"
	"recharge/models"
	"recharge/sys"
	"recharge/utils"
	"recharge/utils/interface_config"
	"strings"
)

type RechargeQuery struct {
	KeepSession
}

// 充值单笔查询
// @router /merchant/recharge_query/?:params [get]
func (the *RechargeQuery) RechargeQuery() {
	queryId := the.GetString(":params")

	record := rechargeMdl.SelectOneRechargeRecord(queryId)
	merchant := merchantMdl.SelectOneMerchantByNo(record.MerchantNo)

	var msg = utils.SUCCESS_STRING
	var flag = utils.FAILED_FLAG

	//只查询处理中的订单
	if strings.Compare(utils.I, record.Status) == 0 {
		// 多通道充值
		switch merchant.ChannelType {
		case utils.XF:
			msg, flag = xfRechargeQuery(record, merchant, msg, flag)
		}
	} else {
		msg = "只查询处理中的订单！"
	}

	the.Data["json"] = globalMethod.JsonFormat(flag, "", msg, "")
	the.ServeJSON()
	the.StopRun()
}

// 先锋通道查询
func xfRechargeQuery(record models.RechargeRecord, merchant models.Merchant, msg string, flag int) (string, int) {
	//先锋
	result, err := xfRechargeQueryReq(record, merchant.SecretKey)
	sys.LogInfo("先锋返回查询信息:", string(result))
	if err != nil {
		return err.Error(), flag
	}

	resp := models.XFRechargeResponseBody{}
	err = json.Unmarshal(result, &resp)
	if err != nil {
		sys.LogError("response data format is error:", err)
		return "先锋充值查询响应数据格式错误", flag
	}

	if strings.Compare("00000", resp.ResCode) != 0 {
		record.EditTime = globalMethod.GetNowTime()
		record.Remark = resp.ResMessage
		rechargeMdl.UpdateRechargeRecord(record)
		return "先锋充值查询错误：" + resp.ResMessage, flag
	}

	record.EditTime = globalMethod.GetNowTime()
	record.Status = resp.Status
	record.Remark = resp.ResMessage

	switch resp.Status {
	case utils.S:
		// 加款
		flag = userMdl.SelectOneUserAddition(record.UserId, record.ReAmount, record)
		if flag > 0 {
			sys.LogInfo("先锋充值订单:", record.ReOrderId, "加款成功")
		} else {
			sys.LogInfo("先锋充值订单:", record.ReOrderId, "加款失败")
		}
	case utils.F:
		msg = resp.ResMessage
		flag = rechargeMdl.UpdateRechargeRecord(record)
	case utils.I:
		msg = "订单处理中，查询信息：" + resp.ResMessage
	}

	return msg, flag
}

// 先锋道通充值查询
func xfRechargeQueryReq(record models.RechargeRecord, key string) ([]byte, error) {
	// 请求参数
	reqSn := globalMethod.GetNowTimeV2() + globalMethod.RandomString(12)
	reqParams := url.Values{}
	reqParams.Add("service", "REQ_RECHARGE_QUERY")
	reqParams.Add("secId", interface_config.SECID)
	reqParams.Add("version", interface_config.VERSION)
	reqParams.Add("reqSn", reqSn)
	reqParams.Add("merchantId", record.MerchantNo)

	// 需要的加密参数
	dataParams := models.XFRechargeQueryData{}
	dataParams.MerchantNo = record.ReOrderId

	// 加密参数
	dataString, _ := json.Marshal(&dataParams)
	data, err := AES.AesEncrypt(string(dataString), key)
	if err != nil {
		return nil, err
	}

	reqParams.Add("data", data)

	// 生成签名
	respParams := map[string]string{}
	respParams["service"] = "REQ_RECHARGE_QUERY"
	respParams["secId"] = interface_config.SECID
	respParams["version"] = interface_config.VERSION
	respParams["reqSn"] = reqSn
	respParams["merchantId"] = record.MerchantNo
	respParams["data"] = data
	params := globalMethod.ToStringByMap(respParams)

	signBytes, err := merchantImpl.XFGenerateSign(params, key)
	if err != nil {
		s := "先锋充值查询生成签名失败"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}
	reqParams.Add("sign", string(signBytes))

	// 发送请求
	resp, err := http.PostForm(interface_config.XF_RECHANGE_URL, reqParams)
	if err != nil {
		s := "先锋充值查询请求失败"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}

	// 处理响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		s := "先锋充值查询响应为空"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}
	defer resp.Body.Close()

	bytes, err := AES.AesDecrypt(body, []byte(key))
	if err != nil {
		s := "先锋充值查询响应解密错误"
		sys.LogTrace(s, err)
		return nil, errors.New(s)
	}

	return bytes, err
}
